package com.ziyun.erp.modules.storeMaterialCheck.service.impl;

import com.baomidou.mybatisplus.mapper.Wrapper;
import com.utility.New;
import com.ziyun.erp.common.utils.PurchaseUtils;
import com.ziyun.erp.modules.material.entity.ErpStockEntity;
import com.ziyun.erp.modules.material.entity.storeStockMaterialEntity;
import com.ziyun.erp.modules.material.service.ErpStockService;
import com.ziyun.erp.modules.material.service.StoreStockMaterialService;
import com.ziyun.erp.modules.purchase.entity.StorePurchaseApplyEntity;
import com.ziyun.erp.modules.storeMaterialCheck.entity.StoreMaterialCheckDetailEntity;
import com.ziyun.erp.modules.storeMaterialCheck.service.StoreMaterialCheckDetailService;
import com.ziyun.erp.modules.storeMaterialCheck.vo.MaterialCheckVo;
import com.ziyun.erp.modules.storeMaterialCheck.vo.StoreMaterialCheckDetailVo;
import com.ziyun.erp.modules.storeMaterialIn.entity.StoreMaterialInEntity;
import com.ziyun.erp.modules.storeMaterialIn.service.StoreMaterialInService;
import com.ziyun.erp.modules.storeMaterialInDetail.entity.StoreMaterialInDetailEntity;
import com.ziyun.erp.modules.storeMaterialInDetail.service.StoreMaterialInDetailService;
import com.ziyun.erp.modules.storeMaterialOut.entity.StoreMaterialOutDetailEntity;
import com.ziyun.erp.modules.storeMaterialOut.entity.StoreMaterialOutEntity;
import com.ziyun.erp.modules.storeMaterialOut.service.StoreMaterialOutDetailService;
import com.ziyun.erp.modules.storeMaterialOut.service.StoreMaterialOutService;
import com.ziyun.erp.modules.storeStockMaterialIo.entity.StoreStockMaterialIoEntity;
import com.ziyun.erp.modules.storeStockMaterialIo.service.StoreStockMaterialIoService;
import io.renren.common.exception.RRException;
import io.renren.common.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;

import com.ziyun.erp.modules.storeMaterialCheck.dao.StoreMaterialCheckDao;
import com.ziyun.erp.modules.storeMaterialCheck.entity.StoreMaterialCheckEntity;
import com.ziyun.erp.modules.storeMaterialCheck.service.StoreMaterialCheckService;
import org.springframework.transaction.annotation.Transactional;


@Service("storeMaterialCheckService")
public class StoreMaterialCheckServiceImpl extends ServiceImpl<StoreMaterialCheckDao, StoreMaterialCheckEntity> implements StoreMaterialCheckService {

    @Autowired
    private StoreMaterialCheckDetailService storeMaterialCheckDetailService;

    @Autowired
    private StoreMaterialOutService storeMaterialOutService;

    @Autowired
    private StoreMaterialOutDetailService storeMaterialOutDetailService;

    @Autowired
    private StoreStockMaterialService storeStockMaterialService;

    @Autowired
    private StoreStockMaterialIoService storeStockMaterialIoService;

    @Autowired
    private ErpStockService erpStockService;

    @Autowired
    private StoreMaterialInService storeMaterialInService;

    @Autowired
    private StoreMaterialInDetailService storeMaterialInDetailService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<StoreMaterialCheckEntity> page = this.selectPage(
                new Query<StoreMaterialCheckEntity>(params).getPage(),
                new EntityWrapper<StoreMaterialCheckEntity>()
        );

        return new PageUtils(page);
    }


    @Override
    public R checkInfo(Integer checkId) {
        List<StoreMaterialCheckDetailVo> resultList = this.baseMapper.getCheckInfo(checkId);
        return R.ok().put("storeMaterialCheckDetailVoList",resultList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R auditCheck(MaterialCheckVo materialCheckVo) {
        //审核通过
        String checkName = materialCheckVo.getCheckName();
        StoreMaterialCheckEntity storeMaterialCheckEntity = materialCheckVo.getStoreMaterialCheck();
        List<StoreMaterialCheckDetailVo> storeMaterialCheckDetailVoList = materialCheckVo.getStoreMaterialCheckDetailVoList();
        if(storeMaterialCheckDetailVoList != null && storeMaterialCheckDetailVoList.size() > 0){
            BigDecimal zero = new BigDecimal(0);
            List<StoreMaterialCheckDetailEntity> updateCheckDetailList = New.arrayList();
            List<StoreMaterialCheckDetailVo> panYinCheckDetailVoList = New.arrayList();
            List<StoreMaterialCheckDetailVo> panKuiCheckDetailVoList = New.arrayList();
            for (StoreMaterialCheckDetailVo storeMaterialCheckDetailVo : storeMaterialCheckDetailVoList) {
                if(storeMaterialCheckDetailVo.getStatus().intValue() == 1){
                    //待审核,跳过
                    continue;
                }else{
                    //审核过了的
                    StoreMaterialCheckDetailEntity storeMaterialCheckDetailEntity = new StoreMaterialCheckDetailEntity();
                    storeMaterialCheckDetailEntity.setDetailId(storeMaterialCheckDetailVo.getDetailId());
                    storeMaterialCheckDetailEntity.setStatus(storeMaterialCheckDetailVo.getStatus());
                    updateCheckDetailList.add(storeMaterialCheckDetailEntity);
                    if(storeMaterialCheckDetailVo.getStatus().intValue() == 2){
                        //审核通过-->生成对应的盘盈盘亏操作
                        //计算盘点结果
                        BigDecimal result = storeMaterialCheckDetailVo.getActualQuantity().subtract(storeMaterialCheckDetailVo.getSystemQuantity());
                        storeMaterialCheckDetailVo.setCheckResult(result.abs());
                        if(result.compareTo(zero) == 1){
                            //实际库存大于系统库存
                            panYinCheckDetailVoList.add(storeMaterialCheckDetailVo);
                        }else if(result.compareTo(zero) == -1){
                            //实际库存小于系统库存
                            panKuiCheckDetailVoList.add(storeMaterialCheckDetailVo);
                        }else{
                            //实际库存等于系统库存-->不做任何处理
                        }
                    }else if(storeMaterialCheckDetailVo.getStatus().intValue() == 3){
                        //驳回-->无特殊操作
                    }else{
                        throw new RRException("盘点单审核状态异常");
                    }
                }
            }
            //循环完毕,修改对应盘点详细记录的审核状态
            if(updateCheckDetailList != null && updateCheckDetailList.size() > 0){
                storeMaterialCheckDetailService.updateBatchById(updateCheckDetailList);
            }
            //根据stockId获得sellerId
            ErpStockEntity erpStockEntity = erpStockService.selectById(storeMaterialCheckEntity.getStockId());
            int sellerId = Integer.parseInt(erpStockEntity.getInstitution());
            //panYinCheckDetailVoList   --   panKuiCheckDetailVoList
            if(panYinCheckDetailVoList != null && panYinCheckDetailVoList.size() > 0){
                handlerPanYinList(sellerId,checkName,storeMaterialCheckEntity,panYinCheckDetailVoList);
            }
            if(panKuiCheckDetailVoList != null && panKuiCheckDetailVoList.size() > 0){
                handlerPanKuiList(sellerId,checkName,storeMaterialCheckEntity,panKuiCheckDetailVoList);
            }
        }
        return R.ok();
    }

    //处理盘亏
    private void handlerPanKuiList(Integer sellerId,String checkName,StoreMaterialCheckEntity storeMaterialCheckEntity,List<StoreMaterialCheckDetailVo> panKuiCheckDetailVoList) {
        BigDecimal zero = new BigDecimal(0);
        // 采购申请单号
        String checkOutNo = PurchaseUtils.producePurchaseApplyNo("CO",sellerId);
        //判断采购申请单号是否重复
        boolean isRepeat = false;
        do {
            List<StoreMaterialOutEntity> storeMaterialOutList = storeMaterialOutService.selectList(
                    new EntityWrapper<StoreMaterialOutEntity>().eq("out_no",checkOutNo)
            );
            if(storeMaterialOutList != null && storeMaterialOutList.size() > 0){
                isRepeat = true;
                checkOutNo = PurchaseUtils.producePurchaseApplyNo("CO",sellerId);
            }else{
                isRepeat = false;
            }
        }while (isRepeat);

        //写入盘亏单总表
        StoreMaterialOutEntity storeMaterialOutEntity = new StoreMaterialOutEntity();
        storeMaterialOutEntity.setOutNo(checkOutNo);
        storeMaterialOutEntity.setStockId(storeMaterialCheckEntity.getStockId());
        storeMaterialOutEntity.setType(5);
        storeMaterialOutEntity.setStatus(2);
        storeMaterialOutEntity.setRemark("系统盘亏数据");
        storeMaterialOutEntity.setCheckName(checkName);
        storeMaterialOutEntity.setCreateName(storeMaterialCheckEntity.getCreateName());
        storeMaterialOutService.insert(storeMaterialOutEntity);
        //写入盘库明细表
        List<StoreMaterialOutDetailEntity> storeMaterialOutDetailEntityList = New.arrayList();
        for (StoreMaterialCheckDetailVo storeMaterialCheckDetailVo : panKuiCheckDetailVoList) {
            StoreMaterialOutDetailEntity storeMaterialOutDetailEntity = new StoreMaterialOutDetailEntity();
            storeMaterialOutDetailEntity.setOutId(storeMaterialOutEntity.getOutId());
            storeMaterialOutDetailEntity.setOutNo(storeMaterialOutEntity.getOutNo());
            storeMaterialOutDetailEntity.setMaterialId(storeMaterialCheckDetailVo.getMaterialId());
            storeMaterialOutDetailEntity.setMaterialQuantity(storeMaterialCheckDetailVo.getCheckResult());
            storeMaterialOutDetailEntity.setUnitMoney(storeMaterialCheckDetailVo.getCost());
            storeMaterialOutDetailEntity.setTotalMoney(storeMaterialCheckDetailVo.getCost().multiply(storeMaterialCheckDetailVo.getCheckResult()));
            storeMaterialOutDetailEntity.setUnit(storeMaterialCheckDetailVo.getUnit());
            storeMaterialOutDetailEntity.setRemark("系统盘亏数据详细记录");
            storeMaterialOutDetailEntity.setCreateName(storeMaterialCheckEntity.getCreateName());
            storeMaterialOutDetailEntity.setTempResult(storeMaterialCheckDetailVo.getCheckResult());
            storeMaterialOutDetailEntityList.add(storeMaterialOutDetailEntity);
        }
        //写入库存记录
        //查询当前是否会出现插入后库存为负数的idStoreMaterialOutDetailEntity storeMaterialOutDetailEntity : storeMaterialOutDetailEntityList
        List<StoreStockMaterialIoEntity> storeStockMaterialIoList = New.arrayList();
        for (int i = 0;i<storeMaterialOutDetailEntityList.size();i++) {
            StoreMaterialOutDetailEntity storeMaterialOutDetailEntity = storeMaterialOutDetailEntityList.get(i);
            storeStockMaterialEntity storeStockMaterialEntity = null;
            try {
                storeStockMaterialEntity = storeStockMaterialService.selectOne(new EntityWrapper<storeStockMaterialEntity>()
                        .eq("stock_id", storeMaterialOutEntity.getStockId())
                        .eq("material_id", storeMaterialOutDetailEntity.getMaterialId()));
            }catch (Exception e){
                throw new RRException("一个门店发现多个耗材id");
            }
            if(storeStockMaterialEntity == null){
                throw new RRException("未找到门店耗材信息异常:门店stockId:"+storeMaterialOutEntity.getStockId()+"耗材id:"+storeMaterialOutDetailEntity.getMaterialId());
            }
            if(storeStockMaterialEntity.getMaterialQuantity().subtract(storeMaterialOutDetailEntity.getTempResult()).compareTo(zero) == -1){
                //库存减少会小于0,该单不更;
                storeMaterialOutDetailEntityList.remove(i);
                i--;
            }else{
                //库存减少不会小于0的,更新库存和io记录
                storeStockMaterialService.checkOutUpdate(storeStockMaterialEntity.getStockMaterialId(),storeMaterialOutDetailEntity.getTempResult());
                //创建io记录
                StoreStockMaterialIoEntity storeStockMaterialIoEntity = new StoreStockMaterialIoEntity();
                storeStockMaterialIoEntity.setTicketsNo(storeMaterialOutEntity.getOutNo());
                storeStockMaterialIoEntity.setMaterialId(Integer.parseInt(storeMaterialOutDetailEntity.getMaterialId()));
                storeStockMaterialIoEntity.setMaterialQuantity(storeMaterialOutDetailEntity.getTempResult());
                storeStockMaterialIoEntity.setUnit(storeMaterialOutDetailEntity.getUnit());
                storeStockMaterialIoEntity.setStockId(storeMaterialCheckEntity.getStockId());
                storeStockMaterialIoEntity.setType(5);
                storeStockMaterialIoEntity.setDirection(-1);
                storeStockMaterialIoEntity.setUnitCost(storeStockMaterialEntity.getCost());
                storeStockMaterialIoEntity.setTotalCost(storeStockMaterialEntity.getCost().multiply(storeMaterialOutDetailEntity.getTempResult()));
                storeStockMaterialIoEntity.setCalculated(0);
                storeStockMaterialIoEntity.setCreateName(storeMaterialCheckEntity.getCreateName());
                storeStockMaterialIoEntity.setRemark("系统盘亏出库io操作记录");
                storeStockMaterialIoList.add(storeStockMaterialIoEntity);
            }
        }
        if(storeStockMaterialIoList != null && storeStockMaterialIoList.size() > 0){
            storeStockMaterialIoService.insertBatch(storeStockMaterialIoList);
        }

        //保存出库记录
        if(storeMaterialOutDetailEntityList != null && storeMaterialOutDetailEntityList.size() > 0){
            storeMaterialOutDetailService.insertBatch(storeMaterialOutDetailEntityList);
        }else{
            throw new RRException("创建盘亏明细单失败,不能为空");
        }
    }

    //处理盘盈
    private void handlerPanYinList(Integer sellerId,String checkName,StoreMaterialCheckEntity storeMaterialCheckEntity,List<StoreMaterialCheckDetailVo> panYinCheckDetailVoList) {
        BigDecimal zero = new BigDecimal(0);
        // 采购申请单号
        String checkInNo = PurchaseUtils.producePurchaseApplyNo("CI",sellerId);
        //判断采购申请单号是否重复
        boolean isRepeat = false;
        do {
            List<StoreMaterialInEntity> storeMaterialOutList = storeMaterialInService.selectList(
                    new EntityWrapper<StoreMaterialInEntity>().eq("in_no",checkInNo)
            );
            if(storeMaterialOutList != null && storeMaterialOutList.size() > 0){
                isRepeat = true;
                checkInNo = PurchaseUtils.producePurchaseApplyNo("CI",sellerId);
            }else{
                isRepeat = false;
            }
        }while (isRepeat);
        //写入盘亏单总表
        StoreMaterialInEntity storeMaterialInEntity = new StoreMaterialInEntity();
        storeMaterialInEntity.setInNo(checkInNo);
        //        storeMaterialInEntity.setTotalMoney();
        storeMaterialInEntity.setTax(0);
        storeMaterialInEntity.setStockId(storeMaterialCheckEntity.getStockId());
        storeMaterialInEntity.setType(3);
        storeMaterialInEntity.setDirection(1);
        storeMaterialInEntity.setStatus(2);
        storeMaterialInEntity.setRemark("系统盘盈数据");
        storeMaterialInEntity.setCreateName(storeMaterialCheckEntity.getCreateName());
        storeMaterialInEntity.setCheckName(checkName);
        storeMaterialInEntity.setPaymentStatus("true");
        storeMaterialInEntity.setPaymentDate(new Date());
        storeMaterialInEntity.setPaymentRemark("系统盘盈记录,无实际财务付款");
        storeMaterialInService.insert(storeMaterialInEntity);
        List<StoreMaterialInDetailEntity> storeMaterialInDetailList = New.arrayList();
        List<StoreStockMaterialIoEntity> storeStockMaterialIoList = New.arrayList();
        for (StoreMaterialCheckDetailVo storeMaterialCheckDetailVo : panYinCheckDetailVoList) {
            StoreMaterialInDetailEntity storeMaterialInDetailEntity = new StoreMaterialInDetailEntity();
//            StoreMaterialOutDetailEntity storeMaterialOutDetailEntity = new StoreMaterialOutDetailEntity();
            storeMaterialInDetailEntity.setInId(storeMaterialInEntity.getInId());
            storeMaterialInDetailEntity.setInNo(storeMaterialInEntity.getInNo());
            storeMaterialInDetailEntity.setMaterialId(storeMaterialCheckDetailVo.getMaterialId());
            storeMaterialInDetailEntity.setMaterialQuantity(storeMaterialCheckDetailVo.getCheckResult());
            storeMaterialInDetailEntity.setUnitMoney(storeMaterialCheckDetailVo.getCost());
            storeMaterialInDetailEntity.setTotalMoney(storeMaterialCheckDetailVo.getCost().multiply(storeMaterialCheckDetailVo.getCheckResult()));
            storeMaterialInDetailEntity.setUnit(storeMaterialCheckDetailVo.getUnit());
            storeMaterialInDetailEntity.setRemark("系统盘盈数据详细记录");
            storeMaterialInDetailEntity.setCreateName(storeMaterialCheckEntity.getCreateName());
            storeMaterialInDetailList.add(storeMaterialInDetailEntity);

            storeStockMaterialService.checkInUpdate(storeMaterialCheckEntity.getStockId(),storeMaterialCheckDetailVo.getMaterialId(),storeMaterialCheckDetailVo.getCheckResult());

            //创建io记录
            StoreStockMaterialIoEntity storeStockMaterialIoEntity = new StoreStockMaterialIoEntity();
            storeStockMaterialIoEntity.setTicketsNo(storeMaterialInEntity.getInNo());
            storeStockMaterialIoEntity.setMaterialId(Integer.parseInt(storeMaterialInDetailEntity.getMaterialId()));
            storeStockMaterialIoEntity.setMaterialQuantity(storeMaterialInDetailEntity.getMaterialQuantity());
            storeStockMaterialIoEntity.setUnit(storeMaterialInDetailEntity.getUnit());
            storeStockMaterialIoEntity.setStockId(storeMaterialCheckEntity.getStockId());
            storeStockMaterialIoEntity.setType(3);
            storeStockMaterialIoEntity.setDirection(1);
            storeStockMaterialIoEntity.setUnitCost(storeMaterialInDetailEntity.getUnitMoney());
            storeStockMaterialIoEntity.setTotalCost(storeMaterialInDetailEntity.getTotalMoney());
            storeStockMaterialIoEntity.setCalculated(0);
            storeStockMaterialIoEntity.setCreateName(storeMaterialCheckEntity.getCreateName());
            storeStockMaterialIoEntity.setRemark("系统盘存入库io操作记录");
            storeStockMaterialIoList.add(storeStockMaterialIoEntity);
        }
        if(storeStockMaterialIoList != null && storeStockMaterialIoList.size() > 0){
            storeStockMaterialIoService.insertBatch(storeStockMaterialIoList);
        }
        //保存出库记录
        if(storeMaterialInDetailList != null && storeMaterialInDetailList.size() > 0){
            storeMaterialInDetailService.insertBatch(storeMaterialInDetailList);
        }else{
            throw new RRException("创建盘存明细单失败,不能为空");
        }
    }


}
